﻿#include <QCoreApplication>
#include <QVector>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <string>
#include <QFile>
#include "cmdlineparser.h"
#include "tb_interface.h"
using namespace TASKBUS;
const int OFFLINEDEBUG = 0;
//数据源方法
int do_mod_fm_dem(const cmdlineParser & args);
//全局的终止标记
static bool bfinished = false;
using namespace std;
int main(int argc , char * argv[])
{
	QCoreApplication a(argc, argv);
	//重要！设置输入输出为二进制！
	init_client();

	//解释命令行
	cmdlineParser args;
	if (OFFLINEDEBUG==0)
		args.parser(argc,argv);
	else
	{
		FILE * old_stdin, *old_stdout;
		auto ars = debug("/home/cestdio_studio/projects/taskbus/bin_linux_64/bin/debug/pid4113",&old_stdin,&old_stdout);
		args.parser(ars);
	}

	int ret = 0;
	//每个模块要响应 --information参数,打印自己的功能定义字符串。或者提供一个json文件。
	if (args.contains("information"))
	{
		QFile fp(":/mod_fm_dem.json");
		fp.open(QIODevice::ReadOnly);
		if (fp.isOpen())
		{
			QByteArray arr = fp.readAll();
			arr.push_back('\0');
			puts(arr.constData());
			fflush(stdout);
		}

		return 0;
	}
	else if (args.contains("function"/*,"mod_fm"*/))//正常运行模式
	{
		ret = do_mod_fm_dem(args);
	}
	else
	{
		fprintf(stderr,"Error:Function does not exits.");
		ret = -1;
	}

	return ret;
}

#define Pi 3.14159265354
int do_mod_fm_dem(const cmdlineParser & args)
{
	using namespace TASKBUS;
	int res = 0;
	//获得平台告诉自己的实例名
	const unsigned int instance	  = args.toInt("instance",0);
	const unsigned int itmstamp_in  = args.toUInt("tmstamp_in",0);
	const unsigned int itmstamp_out = args.toUInt("tmstamp_out",0);
	const unsigned int isig  = args.toInt("signal",0);
	const unsigned int osound	  = args.toInt("sound",0);
	//工作模式
	try{
		//判断参数合法性
		if (instance==0)
			throw "function=quit;{\"error\":\"instance is 0, quit.\"}";
		int failed_header = 0;
		int last_i = 0, last_q = 0;
		while (false==bfinished)
		{
			subject_package_header header;
			vector<unsigned char> packagedta = pull_subject(&header);
			if (is_valid_header(header)==false)
			{
				if (++failed_header>16)
					bfinished = true;
				continue;
			}
			if ( is_control_subject(header))
			{
				//收到命令进程退出的广播消息,退出
				if (strstr(control_subject(header,packagedta).c_str(),"function=quit;")!=nullptr)
					bfinished = true;
			}
			else if (header.subject_id==itmstamp_in)
			{
				const unsigned char * pdta = (unsigned char *) packagedta.data();
				if (itmstamp_out)
				{
					push_subject(itmstamp_out,instance,packagedta.size(),
								 pdta
								 );
				}
			}
			else if (header.subject_id == isig)
			{
				std::vector<short> vec_output;

				const unsigned char * pdta = packagedta.data();
				const int nPts = header.data_length / sizeof(short)/2;
				const short (* pdata)[2] = (const short (*)[2])pdta;
				for (int j=0;j<nPts;++j)
				{
					//前后差分
					int curr_i = pdata[j][0];
					int curr_q = pdata[j][1];
					//Diff for e(ja(t)) * e(-ja(t+1)), diff  phase  = freq
					// (lastI + j*lastQ) * (currI - j * currQ)
					int diff_i = last_i * curr_i + last_q * curr_q;
					int diff_q = last_q * curr_i - last_i * curr_q;
					double angle = 0;
					//计算角度
					if (diff_i==0)
						angle = (diff_q>0)? Pi/2:-Pi/2;
					else if (diff_i >0 )
						angle = atan(diff_q*1.0/diff_i);
					else if (diff_q >=0)
						angle = atan(diff_q*1.0/diff_i)+Pi;
					else
						angle = atan(diff_q*1.0/diff_i)-Pi;

					last_i = curr_i;
					last_q = curr_q;

					vec_output.push_back(angle/Pi*4096);

				}
				//播发
				if (osound)
				{
					push_subject(osound,instance,vec_output.size()*2,
								 (unsigned char *)vec_output.data()
								 );
				}


			}
		}


	}
	catch (const char * errMessage)
	{
		//向所有部位广播，偶要退出。
		push_subject(control_subect_id(),/*instance,broadcast_destin_id(),*/0,errMessage);
		fprintf(stderr,"Error:%s.",errMessage);
		fflush (stderr);
		res = -1;
	}

	return res;
}

